package com.li.service.impl;

import com.li.config.RedisConfig;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import com.li.controller.JHSTaskController;
import com.li.entities.Product;
import com.li.service.JHSTaskService;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class JHSTaskServiceImpl implements JHSTaskService {
    @Resource
    private RedisTemplate template;

    /**
     * 如果执行到4,有用户查数据
     */
    @Override
    @PostConstruct
    public void initJHS() {
        log.info("启动定时器天猫聚划算模拟功能开始...");
//1.用多线程模拟定时任务,后台任务定时将mysql 里面的特价商品刷新到Redis里
        new Thread(()->{
            //2.模拟MySQL查出数据,加载到Redis并给聚划算显示
            List<Product> list = this.getProductSimulatedMySQLData();
            this.updateCache2(list);
            //5.暂停1分钟线程,间隔一分钟执行一次,一分钟模拟一天
            try {
                Thread.sleep(60000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            log.info("run JHS 定时刷新");
        },"t1").start();
    }

    /**
     * 问题: 3,4 不是原子命令
     * 执行到3,未执行4时 用户访问到缓存,缓存失效 ->直接打到数据库
     * @param list
     */
    public void updateCache(List<Product> list){
        //3.采用redis list数据结构lpush 命令来实现存储
        template.delete(JHSTaskController.JHS_KEY);
        //4.加入最新的数据给redis参加活动
        template.opsForList().leftPushAll(JHSTaskController.JHS_KEY,list);
    }
    /**
     * todo 集群
     * @param list
     */
    public void updateCache2(List<Product> list){
        //3.先更新B缓存且让B缓存过期时间超过A缓存,如果A忽然失效还有B兜底,防止击穿
        template.delete(JHSTaskController.JHS_KEY_B);
        template.opsForList().leftPushAll(JHSTaskController.JHS_KEY_B,list);
        //注意,差异时间,B过期时间晚10s
        template.expire(JHSTaskController.JHS_KEY_B,60*60*24*7+10L, TimeUnit.SECONDS);
        //4.在更新A缓存
        template.delete(JHSTaskController.JHS_KEY_A);
        template.opsForList().leftPushAll(JHSTaskController.JHS_KEY_A,list);
        template.expire(JHSTaskController.JHS_KEY_A,60*60*24*7L, TimeUnit.SECONDS);
    }
    private List<Product> getProductSimulatedMySQLData(){
        ArrayList<Product> list = new ArrayList<>();
        for (int i = 0; i < 20; i++) {
            int id = new Random().nextInt(10000);
            Product product = new Product((long) id, "商品" + id, i, "详情" + id);
            list.add(product);
        }
        return list;
    }
    @Override
    public List<Product> getProductsFromMysql() {
        return null;
    }
}
